/*
 * @Description 
 * @Autor lzhiqiang
 * @Date 2023-03-19 13:57:04
 * @LastEditors lzhiqiang
 * @LastEditTime 2023-03-20 11:15:22
 */
#include "log.h"
#include "iomanager.h"
#include "tcp_server.h"
#include "bytearray.h"
#include "address.h"


static johnsonli::Logger::ptr g_logger = LOG_ROOT();

class EchoServer : public johnsonli::TcpServer
{
public:
    EchoServer(int type);
    void handleClient(johnsonli::Socket::ptr client);

private:
    //1：字符输出
    //2：二进制输出
    int m_type = 1;
};

EchoServer::EchoServer(int type)
    :m_type(type) 
{}

void EchoServer::handleClient(johnsonli::Socket::ptr client) 
{
    LOG_INFO(g_logger) << "handleClient " << *client;  
    johnsonli::ByteArray::ptr ba(new johnsonli::ByteArray);
    while(true)
    {
        ba->clear();
        std::vector<iovec> iovs;
        ba->getWriteBuffers(iovs, 1024);

        //收数据
        int rt = client->recv(&iovs[0], iovs.size());
        if(rt == 0)
        {
            //对端关闭
            LOG_INFO(g_logger) << "client close: " << *client;
            break;
        }
        else if(rt < 0)
        {
            LOG_INFO(g_logger) << "client error rt=" << rt
                << " errno=" << errno << " errstr=" << strerror(errno);
            break;
        }

        ba->setPosition(ba->getPosition() + rt);
        ba->setPosition(0);

        if(m_type == 1) 
        {//text 
            std::cout << ba->toString();// << std::endl;
        } 
        else 
        {
            std::cout << ba->toHexString();// << std::endl;
        }
        std::cout.flush();
    }   
}

int type = 1;

void test() 
{
    LOG_INFO(g_logger) << "server type=" << type;
    EchoServer::ptr es(new EchoServer(type));
    auto addr = johnsonli::Address::LookupAny("0.0.0.0:8020");
    while(!es->bind(addr)) {
        sleep(2);
    }
    es->start();
}

int main(int argc, char** argv)
{
    if(argc < 2) 
    {
        LOG_INFO(g_logger) << "used as[" << argv[0] << " -t] or [" << argv[0] << " -b]";
        return 0;
    }

    if(!strcmp(argv[1], "-b")) {
        type = 2;
    }

    johnsonli::IOManager iom(1);
    iom.schedule(test);
    return 0;
}